/*MyPhotoIndex Free Photo Organizer <www.myphotoindex.com>
  Copyright (C) <2006-2009>  <Asaf Yarkoni asaf@yarkoni.net>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using MyPhotoIndex.Utilities;

namespace MyPhotoIndex.Controls
{
    public partial class ProgressForm : FormTemplate
    {
        private String m_caption;
        private Image m_icon;
        private bool m_stop;

        public event EventHandler<EventArgs> FormVisibleEvent;

        public ProgressForm(String caption, Image icon, int maximum)
        {
            InitializeComponent();
          //  ProgressForm.CheckForIllegalCrossThreadCalls = false;
            m_caption = caption;
            m_icon = icon;
            SetMaximum(maximum);
        }

        private void ProgressForm_Load(object sender, EventArgs e)
        {
            this.Text = m_caption;
            this.pictureBox1.Image = m_icon;

            while (this.Opacity < 1)
            {
                Application.DoEvents();
                Thread.Sleep(10);
            }

            if (FormVisibleEvent != null)
            {
                FormVisibleEvent.Invoke(this, EventArgs.Empty);
            }

            timer1.Tick += new EventHandler(timer1_Tick);
            timer1.Enabled = true;
        }

        void timer1_Tick(object sender, EventArgs e)
        {
            Activate();
            BringToFront();
        }

        public void SetMaximum(int value)
        {
            this.progressBar1.Maximum = value;
        }

        public void SetValue(int value)
        {
            this.progressBar1.Value = value;
        }

        public void Increment()
        {
            this.progressBar1.Value++;
            Application.DoEvents();
        }

        public void Increment(String description, Image image)
        {
            this.progressBar1.Value++;
            this.descriptionLable.Text = description;
            if (this.pictureBox1.Image != null)
            {
                this.pictureBox1.Image.Dispose();
                this.pictureBox1.Image = null;
            }

            this.pictureBox1.Image = new Bitmap(image);
            Application.DoEvents();
        }

        public void MakeInfinite()
        {
            this.progressBar1.Style = ProgressBarStyle.Marquee;
        }

        public bool Stop
        {
            get { return m_stop; }
        }

        protected override void CancelButton_Click(object sender, EventArgs e)
        {
            m_stop = true;
        }
    }

    public class AsyncProgressFormParams
    {
        private IWin32Window m_owner;
        private String m_caption;
        private Image m_icon;
        private int m_maximum;

        public IWin32Window Owner
        {
            get { return m_owner; }
            set { m_owner = value; }
        }

        public String Caption
        {
            get { return m_caption; }
            set { m_caption = value; }
        }

        public Image Icon
        {
            get { return m_icon; }
            set { m_icon = value; }
        }

        public int Maximum
        {
            get { return m_maximum; }
            set { m_maximum = value; }
        }

        public AsyncProgressFormParams(IWin32Window owner, String caption, Image icon, int maximum)
        {
            m_owner = owner;
            m_caption = caption;
            m_icon = icon;
            m_maximum = maximum;
        }
    }

    public class AsyncProgressForm : IDisposable
    {
        private delegate void IntMethodDelegate(int value);
        private delegate void BoolMethodDelegate(bool value);
        private delegate DialogResult ShowDialogMethodDelegate(IWin32Window owner);
        private delegate void VoidMethodDelegate();
        private delegate void IncrementDescriptionImageMethodDelegate(String description, Image image);

        private ProgressForm m_form;
        private bool m_formVisible;
        private bool m_isDisposed;
        private bool m_formClosed = true;

        public AsyncProgressForm(IWin32Window owner, String caption, Image icon, int maximum)
        {
            AsyncProgressFormParams progressParams = new AsyncProgressFormParams(owner, caption, icon, maximum);

            Thread t = new Thread(new ParameterizedThreadStart(ShowModalNoWait));
            t.CurrentUICulture = Thread.CurrentThread.CurrentUICulture;
            t.Start(progressParams);
            while (m_formVisible == false) { Thread.Sleep(10); Application.DoEvents(); }
        }

        private void ShowModalNoWait(Object parameter)
        {
            AsyncProgressFormParams progressParams = (AsyncProgressFormParams)parameter;
            m_form = new ProgressForm(progressParams.Caption,
                                            progressParams.Icon, progressParams.Maximum);

            m_form.FormVisibleEvent += new EventHandler<EventArgs>(m_form_FormVisibleEvent);
            m_form.FormClosed += new FormClosedEventHandler(m_form_FormClosed);
            m_form.LostFocus += new EventHandler(m_form_LostFocus);
            m_form.Deactivate += new EventHandler(m_form_Deactivate);
            try
            {
                m_form.StartPosition = FormStartPosition.CenterScreen;
                m_form.ShowDialog(/*(IWin32Window)progressParams.Owner*/);
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }

            m_formClosed = true;
            m_formVisible = false;

            // m_form.Invoke(new VoidMethodDelegate(m_form.Show)/*, new Object[] { progressParams.Owner }*/);
        }

        void m_form_Deactivate(object sender, EventArgs e)
        {

        }

        void m_form_LostFocus(object sender, EventArgs e)
        {

        }

        void m_form_FormClosed(object sender, FormClosedEventArgs e)
        {
        }

        void m_form_FormVisibleEvent(object sender, EventArgs e)
        {
            m_formVisible = true;
        }

        public int Maximum
        {
            set
            {
                IntMethodDelegate d = new IntMethodDelegate(m_form.SetMaximum);
                m_form.Invoke(d, new object[] { value });
            }
        }

        public int Value
        {
            set
            {
                IntMethodDelegate d = new IntMethodDelegate(m_form.SetValue);
                m_form.Invoke(d, new object[] { value });
            }
        }

        public void Increment()
        {
            VoidMethodDelegate d = new VoidMethodDelegate(m_form.Increment);
            m_form.Invoke(d, new object[] { });
        }

        public void Increment(String description)
        {
            IncrementDescriptionImageMethodDelegate d = new IncrementDescriptionImageMethodDelegate(m_form.Increment);
            m_form.Invoke(d, new object[] { description, null });
        }

        public void Increment(String description, Image image)
        {
            IncrementDescriptionImageMethodDelegate d = new IncrementDescriptionImageMethodDelegate(m_form.Increment);
            m_form.Invoke(d, new object[] { description, image });
        }

        public void MakeInifinte()
        {
            m_form.Invoke(new VoidMethodDelegate(m_form.MakeInfinite));
        }

        public bool Stop
        {
            get { return m_form.Stop; }
        }

        public bool IsDisposed
        {
            get { return m_isDisposed; }
        }

        #region IDisposable Members

        public void Dispose()
        {
            m_isDisposed = true;
            m_formClosed = false;

            VoidMethodDelegate d = new VoidMethodDelegate(m_form.Close);
            m_form.Invoke(d, new object[] { });

            while (m_formClosed == false)
            {
                Thread.Sleep(10);
            }
        }

        #endregion
    }
}